gusucode.com > VC++ 密码探测器 > VC++ 密码探测器/gusucode/PwdSpy/PwdSpyDlg.cpp
// PwdSpyDlg.cpp : implementation file // #include "stdafx.h" #include "PwdSpy.h" #include "PwdSpyDlg.h" #include "PwdSpyHk.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // Register our Window Message // This message is passed to us if the user tries to active multiple copies of the app UINT CPwdSpyDlg::s_wmActivateApp = RegisterWindowMessage(CUSTOM_WNDMSG); ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) virtual BOOL OnInitDialog(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange *pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BOOL CAboutDlg::OnInitDialog() { CDialog::OnInitDialog(); CString strUrl; strUrl.LoadString(IDS_URL); SetDlgItemText(IDC_URL, strUrl); return TRUE; } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CPwdSpyDlg dialog //*********************************************** CPwdSpyDlg::CPwdSpyDlg(CWnd *pParent) : CDialog(CPwdSpyDlg::IDD, pParent) { //{{AFX_DATA_INIT(CPwdSpyDlg) m_strMousePos = _T(""); m_strHwnd = _T(""); m_strCaption = _T(""); m_strWndClass = _T(""); m_strIsPwd = _T(""); m_strPwd = _T(""); //}}AFX_DATA_INIT // Load the icons and cursors m_hIconLarge = (HICON)LoadImage(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), 0); m_hIconSmall = (HICON)LoadImage(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDI_SMALLICON), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0); m_hIconBlank = (HICON)LoadImage(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDI_BLANK_ICON), IMAGE_ICON, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CXICON), 0); m_hIconScan = (HICON)LoadImage(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDI_LOOK_ICON), IMAGE_ICON, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CXICON), 0); m_hCursorScan = (HCURSOR)LoadImage(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDC_LOOK_CUR), IMAGE_CURSOR, GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CXCURSOR), 0); m_hCursorPrev = NULL; m_hWndPrev = m_hWndScanEx = NULL; m_bIsLooking = false; m_bAlwaysOnTop = true; m_nScanLevel = 0; // Use ScanEx if Win2K or WinXP m_bScanEx = (m_osi.IsNT() && m_osi.GetMajor() >= 5) ? true : false; m_wndPopupTip.Create(this); } //*********************************************** CPwdSpyDlg::~CPwdSpyDlg() { // Make absolutely sure we unhook before closing RemoveHook(); if(m_hIconLarge != NULL) DestroyIcon(m_hIconLarge); if(m_hIconSmall != NULL) DestroyIcon(m_hIconSmall); if(m_hIconBlank != NULL) DestroyIcon(m_hIconBlank); if(m_hIconScan != NULL) DestroyIcon(m_hIconScan); if(m_hCursorScan != NULL) DestroyCursor(m_hCursorScan); } //*********************************************** void CPwdSpyDlg::DoDataExchange(CDataExchange *pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CPwdSpyDlg) DDX_Control(pDX, IDC_LOOK, m_ctrlLook); DDX_Text(pDX, IDC_EDIT_MOUSEPOS, m_strMousePos); DDX_Text(pDX, IDC_EDIT_HWND, m_strHwnd); DDX_Text(pDX, IDC_EDIT_CAPTION, m_strCaption); DDX_Text(pDX, IDC_EDIT_WNDCLASS, m_strWndClass); DDX_Text(pDX, IDC_EDIT_ISPWD, m_strIsPwd); DDX_Text(pDX, IDC_EDIT_PWD, m_strPwd); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CPwdSpyDlg, CDialog) //{{AFX_MSG_MAP(CPwdSpyDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_MOUSEMOVE() ON_WM_GETMINMAXINFO() ON_WM_COPYDATA() //}}AFX_MSG_MAP ON_REGISTERED_MESSAGE(s_wmActivateApp, OnActivateApp) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CPwdSpyDlg message handlers //*********************************************** BOOL CPwdSpyDlg::OnInitDialog() { CDialog::OnInitDialog(); // IDM_ALWAYS_ON_TOP must be in the system command range. _ASSERTE((IDM_ALWAYS_ON_TOP & 0xFFF0) == IDM_ALWAYS_ON_TOP); _ASSERTE(IDM_ALWAYS_ON_TOP < 0xF000); // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu *pSysMenu = GetSystemMenu(FALSE); if(pSysMenu != NULL) { // Remove the "Size" and "Maximize" menu options from the system menu pSysMenu->DeleteMenu(SC_SIZE, MF_BYCOMMAND); pSysMenu->DeleteMenu(SC_MAXIMIZE, MF_BYCOMMAND); // Append a separator, Always On Top, and About CString strMenu; pSysMenu->AppendMenu(MF_SEPARATOR); strMenu.LoadString(IDS_ALWAYS_ON_TOP); pSysMenu->AppendMenu(MF_STRING, IDM_ALWAYS_ON_TOP, strMenu); strMenu.LoadString(IDS_ABOUTBOX); _ASSERTE(!strMenu.IsEmpty()); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strMenu); } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIconLarge, TRUE); // Set big icon SetIcon(m_hIconSmall, FALSE); // Set small icon ((CComboBox*)GetDlgItem(IDC_COMBO_LEVEL))->SetCurSel(m_nScanLevel); //窗口总在最上面 OnAlwaysOnTop(); return TRUE; } //*********************************************** void CPwdSpyDlg::OnSysCommand(UINT nID, LPARAM lParam) { if((nID & 0xFFF0) == IDM_ALWAYS_ON_TOP) { m_bAlwaysOnTop ^= true; OnAlwaysOnTop(); } else if((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. //*********************************************** void CPwdSpyDlg::OnPaint() { if(IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM)dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIconLarge); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. //*********************************************** HCURSOR CPwdSpyDlg::OnQueryDragIcon() { return (HCURSOR)m_hIconSmall; } //*********************************************** void CPwdSpyDlg::OnLButtonDown(UINT nFlags, CPoint point) { CWnd *pWnd = ChildWindowFromPoint(point); if(pWnd != NULL && pWnd->GetSafeHwnd() == m_ctrlLook.GetSafeHwnd()) StartLooking(); CDialog::OnLButtonDown(nFlags, point); } //*********************************************** void CPwdSpyDlg::OnLButtonUp(UINT nFlags, CPoint point) { if(m_bIsLooking) StopLooking(); CDialog::OnLButtonUp(nFlags, point); } //*********************************************** void CPwdSpyDlg::StartLooking(void) { m_nScanLevel = ((CComboBox*)GetDlgItem(IDC_COMBO_LEVEL))->GetCurSel(); if(m_nScanLevel == CB_ERR) m_nScanLevel = 0; SetCapture(); m_bIsLooking = true; m_hCursorPrev = SetCursor(m_hCursorScan); m_ctrlLook.SetIcon(m_hIconBlank); } //*********************************************** void CPwdSpyDlg::StopLooking(void) { ReleaseCapture(); m_bIsLooking = false; // If we've hooked another process, remove the hook if(m_bScanEx) RemoveHook(); m_wndPopupTip.HidePopupWindow(); if(m_hWndPrev != NULL) { InvertBorder(m_hWndPrev); m_hWndPrev = NULL; } // SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW)); SetCursor(m_hCursorPrev); m_ctrlLook.SetIcon(m_hIconScan); // Redraw the whole screen ::InvalidateRect(NULL, NULL, FALSE); } //*********************************************** void CPwdSpyDlg::OnMouseMove(UINT nFlags, CPoint point) { if(m_bIsLooking) Scan(point); CDialog::OnMouseMove(nFlags, point); } //*********************************************** // 该函数扫描给定位置的窗口,得到密码 void CPwdSpyDlg::Scan(CPoint point) { _ASSERTE(m_bIsLooking); bool bFound = false; ClientToScreen(&point);//转换到屏幕坐标 m_strMousePos.Format(_T("X=%ld, Y=%ld"), point.x, point.y); m_strHwnd.Empty(); m_strCaption.Empty(); m_strWndClass.Empty(); m_strIsPwd.Empty(); m_strPwd.Empty(); HWND hWnd; // hWnd = ::WindowFromPoint(point); hWnd = SmallestWindowFromPoint(point);//找到包含该点的最小窗口 if(hWnd != NULL) { // 确保找到的窗口不是自己的窗口 if(GetWindowThreadProcessId(GetSafeHwnd(), NULL) != GetWindowThreadProcessId(hWnd, NULL)) { if(hWnd != m_hWndPrev) { // 如果是新的窗口,则把原来老的边界去掉,画新窗口的边界 m_wndPopupTip.HidePopupWindow(); InvertBorder(m_hWndPrev); m_hWndPrev = hWnd; InvertBorder(m_hWndPrev); } TCHAR szBuffer[256]; m_strHwnd.Format(_T("0x%08X"), hWnd); m_strIsPwd.LoadString((m_nScanLevel == 2) ? IDS_NOT_AVAILABLE : IDS_NO); // 得到窗口标题 if(::GetWindowText(hWnd, szBuffer, sizeof(szBuffer) / sizeof(TCHAR))) m_strCaption = szBuffer; // 得到窗口类名字 if(::GetClassName(hWnd, szBuffer, sizeof(szBuffer) / sizeof(TCHAR))) m_strWndClass = szBuffer; if(m_nScanLevel >= 1 || m_strWndClass.CompareNoCase(_T("edit")) == 0) { // 得到窗口风格 long nStyle = ::GetWindowLong(hWnd, GWL_STYLE); if(m_nScanLevel == 2 || nStyle & ES_PASSWORD) { CRect rect; ::GetWindowRect(hWnd, &rect); if(m_nScanLevel == 0) m_strIsPwd.LoadString(IDS_YES); if(m_nScanLevel == 1) m_strIsPwd.LoadString(IDS_MAYBE); bFound = true; //这里用来得到密码. // 如果操作系统是 Win95/98/ME 或者 NT4 ,可以直接从控件得到 // 如果操作系统是 Win2K or WinXP ,必须用钩子以得到密码 if(m_bScanEx) { // Win2K or WinXP if(InstallHook(GetWindowThreadProcessId(hWnd, NULL)))//安装钩子 { if(ScanPassword(hWnd, GetSafeHwnd())) m_hWndScanEx = hWnd, m_ptScanEx = point; } } else { // Win95/98/ME or WinNT *szBuffer = _T('\0'); ::SendMessage(hWnd, WM_GETTEXT, sizeof(szBuffer) / sizeof(TCHAR), (LPARAM)szBuffer); m_strPwd = szBuffer; m_wndPopupTip.ShowPopupWindow(m_strPwd, point, rect); } } } } else { // 窗口属于自己,移除边界 m_wndPopupTip.HidePopupWindow(); InvertBorder(m_hWndPrev); m_hWndPrev = NULL; } } if(!bFound) m_wndPopupTip.HidePopupWindow(); UpdateData(FALSE);//更新数据显示 } //*********************************************** void CPwdSpyDlg::OnAlwaysOnTop() { ::SetWindowPos(GetSafeHwnd(), (m_bAlwaysOnTop) ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); // Check/uncheck the menu item CMenu *pSysMenu = GetSystemMenu(FALSE); if(pSysMenu != NULL) { UINT nFlags = MF_BYCOMMAND | (m_bAlwaysOnTop) ? MF_CHECKED : MF_UNCHECKED; pSysMenu->CheckMenuItem(IDM_ALWAYS_ON_TOP, nFlags); } } //*********************************************** BOOL CPwdSpyDlg::PreTranslateMessage(MSG *pMsg) { if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE && m_bIsLooking) { StopLooking(); return TRUE; } else { return CDialog::PreTranslateMessage(pMsg); } } //*********************************************** void CPwdSpyDlg::OnGetMinMaxInfo(MINMAXINFO FAR *lpMMI) { // This function prevents the dialog from coming up full screen // if the user starts it "maximized" lpMMI->ptMaxSize = CPoint(286, 308); // hard coded numbers, if you resize the dialog you'll have to recalc these CWnd::OnGetMinMaxInfo(lpMMI); } //*********************************************** //找到包含鼠标点的最小窗口 HWND CPwdSpyDlg::SmallestWindowFromPoint(const POINT point) { RECT rect, rectSearch; HWND pWnd, hWnd, hSearchWnd; hWnd = ::WindowFromPoint(point); if(hWnd != NULL) { // 得到本窗口大小和父窗口句柄,以便比较 ::GetWindowRect(hWnd, &rect); pWnd = ::GetParent(hWnd); // 只有该窗口有父亲才继续比较 if(pWnd != NULL) { // 按z方向搜索 hSearchWnd = hWnd; do{ hSearchWnd = ::GetWindow(hSearchWnd, GW_HWNDNEXT); // 是否新找到的窗口也包含该点,并且跟本窗口有同一个父亲,并且是可见的 ::GetWindowRect(hSearchWnd, &rectSearch); if(::PtInRect(&rectSearch, point) && ::GetParent(hSearchWnd) == pWnd && ::IsWindowVisible(hSearchWnd)) { // 哪个更小 if(((rectSearch.right - rectSearch.left) * (rectSearch.bottom - rectSearch.top)) < ((rect.right - rect.left) * (rect.bottom - rect.top))) { // 替换,继续查找 hWnd = hSearchWnd; ::GetWindowRect(hWnd, &rect); } } }while(hSearchWnd != NULL); } } return hWnd; } //*********************************************** void CPwdSpyDlg::InvertBorder(const HWND hWnd) { if(!IsWindow(hWnd)) return; RECT rect; // Get the coordinates of the window on the screen ::GetWindowRect(hWnd, &rect); // Get a handle to the window's device context HDC hDC = ::GetWindowDC(hWnd); // Create an inverse pen that is the size of the window border SetROP2(hDC, R2_NOT); HPEN hPen = CreatePen(PS_INSIDEFRAME, 3 * GetSystemMetrics(SM_CXBORDER), RGB(0,0,0)); // Draw the rectangle around the window HPEN hOldPen = (HPEN)SelectObject(hDC, hPen); HBRUSH hOldBrush = (HBRUSH)SelectObject(hDC, GetStockObject(NULL_BRUSH)); Rectangle(hDC, 0, 0, rect.right - rect.left, rect.bottom - rect.top); SelectObject(hDC, hOldBrush); SelectObject(hDC, hOldPen); // Give the window its device context back, and destroy our pen ::ReleaseDC(hWnd, hDC); DeleteObject(hPen); } //*********************************************** LRESULT CPwdSpyDlg::OnActivateApp(WPARAM wParam, LPARAM lParam) { if(!IsWindowVisible()) ShowWindow(SW_SHOW); if(IsIconic()) ShowWindow(SW_RESTORE); SetForegroundWindow(); return TRUE; } //*********************************************** //消息响应,一旦有数据到来,就调用该函数 BOOL CPwdSpyDlg::OnCopyData(CWnd *pWnd, COPYDATASTRUCT *pCopyDataStruct) { try { if((HWND)pCopyDataStruct->dwData == m_hWndScanEx)//数据发送的窗口是否为正在查询的窗口 { TCHAR szBuffer[256] = {_T('\0')}; DWORD dwSize = sizeof(szBuffer) * sizeof(TCHAR); if(pCopyDataStruct->cbData < dwSize) dwSize = pCopyDataStruct->cbData; CopyMemory(szBuffer, pCopyDataStruct->lpData, dwSize);//密码拷贝 m_strPwd = szBuffer; CRect rect; ::GetWindowRect(m_hWndScanEx, &rect); m_wndPopupTip.ShowPopupWindow(m_strPwd, m_ptScanEx, rect); UpdateData(FALSE);//显示 } } catch(...) {} return TRUE; }